package com.ailk.cuc.autotestbg.xml.business.impl.ess;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;

import com.ailk.cuc.autotestbg.common.business.interf.ReplaceComponentInterface;
import com.ailk.cuc.autotestbg.xml.bean.AutoEssDataBean;
import com.ailk.cuc.autotestbg.xml.constants.EssEcsConstants;
import com.ailk.cuc.autotestbg.xml.exception.EssReplaceException;

public class EssReplaceComponentImpl implements ReplaceComponentInterface {
	
	private static Log logger = LogFactory.getLog(EssReplaceComponentImpl.class);
	
	private AutoEssDataBean essDataBean;
	private Document essDoc = null;
	private Map<String, Object> mapIn;
	
	public void replaceInfo(Map<String, Object> argMapIn,Map<String,Object> argMapOut) throws EssReplaceException {
		// TODO Auto-generated method stub
		essDataBean = (AutoEssDataBean)argMapIn.get("essDataBean");
		long interfaceId = essDataBean.getInterfaceId();
		mapIn = argMapIn;
		logger.info("开始进行报文替换dataId:"+essDataBean.getDataId()+",interfaceId:"+interfaceId);
		
		String rulePath = (String)argMapIn.get(EssEcsConstants.XML_ESS_RULE_PATH);
		if(rulePath == null|| rulePath.trim().equals("")){
			logger.info("没有规则文件，不必替换！");
			return;
		}
		logger.info("规则文件路径："+rulePath);
		File ruleFile = new File(rulePath);
		String replaceRule = null;
		try {
			replaceRule = FileUtils.readFileToString(ruleFile);
			logger.debug("规则文件："+replaceRule);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new EssReplaceException();
		}
		String interfaceIdStr = new Long(interfaceId).toString();
		int index = replaceRule.indexOf(interfaceIdStr);
		String deccRule = replaceRule.substring(index, index+18);
		
		if(deccRule.contains("rule")){
			int beginIndex = replaceRule.indexOf("EOT", index);
			int endIndex = replaceRule.indexOf("EOT", beginIndex+3);
			String subRule = replaceRule.substring(beginIndex+4, endIndex);
			logger.debug("本次替换规则序列："+subRule);
			//替换规则生成xml格式Docuement
			Document ruleDoc = null;
			try {
				ruleDoc = DocumentHelper.parseText(subRule);
			} catch (DocumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw new EssReplaceException();
			}
			Element ruleEle = ruleDoc.getRootElement();
			
			//要替换的xml
			String essMessageXml = null;
			essMessageXml = (String)argMapIn.get(essDataBean.getInterfaceId()+"_request_"+"essMessageXml");
						
			logger.debug("替换前报文："+essMessageXml);
			
			Document mainDoc = null;
			Node servContNode = null;
			try {
				mainDoc = DocumentHelper.parseText(essMessageXml);
				servContNode = mainDoc.selectSingleNode("/UniBSS/SvcCont");
				String subEssMessageXml = servContNode.getText();
				logger.info("替换前报文SUB："+subEssMessageXml);
				essDoc = DocumentHelper.parseText(subEssMessageXml);
			} catch (DocumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw new EssReplaceException();
			}
			Element essEle = essDoc.getRootElement();
			
			relpaceContent(ruleEle,essEle);

			Element ele = (Element)servContNode;
			ele.clearContent();
			ele.addCDATA(essDoc.asXML());
			logger.info("替换后报文SUB："+essDoc.asXML());
			logger.debug("替换后报文："+mainDoc.asXML());
			
			argMapIn.put(essDataBean.getInterfaceId()+"_request_"+"essMessageXml",mainDoc.asXML());
			
			logger.info("完成报文替换dataId:"+essDataBean.getDataId()+",interfaceId:"+interfaceId);
		}else{
			logger.info("不需要进行报文替换dataId:"+essDataBean.getDataId()+",interfaceId:"+interfaceId);
		}

	}
	/*
	 * 遍历替换规则
	 * */
	@SuppressWarnings("unchecked")
	private void relpaceContent(Element ruleElement,Element essElement) throws EssReplaceException {
		try {
			String lyytype = ruleElement.attributeValue("lyytype");
			if(lyytype==null||lyytype.equals("")){
				logger.info("非根节点："+ruleElement.getName());
				Iterator<Element> it = ruleElement.elementIterator();
				while(it.hasNext()){
					Element subRuleEle = it.next();
					relpaceContent(subRuleEle,essElement);
				}
			}else{
				if(lyytype.equals("ARRAY")){
					arrayXml(ruleElement);
				}else if(lyytype.equals("XML")){
					replaceXml(ruleElement);
				}else if(lyytype.equals("DELETE")){
					deleteXml(ruleElement);
				}else if(lyytype.equals("VALUE")){
					valueXml(ruleElement);
				}else if(lyytype.equals("SQL")){
					
				}else{
					logger.error("不存在lyytype为："+lyytype);
					throw new EssReplaceException();
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new EssReplaceException();
		}
	}
	/*
	 * xml替换
	 * */
	private void replaceXml(Element ruleEleXml) throws EssReplaceException{
		logger.info("XML替换"+ruleEleXml.getName());
		String source = ruleEleXml.getTextTrim();
		String[] sourceArray = source.split("\\.");
		String essXpath = ruleEleXml.getPath();
		Node essNode = essDoc.selectSingleNode(essXpath);
		
		String essRspReq = "_request_";
		if(sourceArray[1].endsWith("Rsp")){
			essRspReq = "_response_";
		}
		String essSourceMessageXml = (String)mapIn.get(sourceArray[0]+essRspReq+"essMessageXml");
		if(essSourceMessageXml == null||essSourceMessageXml.trim().equals("")){
			logger.error("源报文为空！");
			return;
		}
		
		Document mainDoc = null;
		try {
			mainDoc = DocumentHelper.parseText(essSourceMessageXml);
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if(mainDoc == null){
			logger.error("源报文不是XML！");
			return;
		}
		Node servContNode = mainDoc.selectSingleNode("/UniBSS/SvcCont");
		essSourceMessageXml = servContNode.getText();
		logger.info("essSourceMessageXml:"+essSourceMessageXml);
		if(essSourceMessageXml == null||essSourceMessageXml.trim().equals("")){
			return;
		}
		
		Document sourceDoc = null;
		try {
			sourceDoc = DocumentHelper.parseText(essSourceMessageXml);
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
			throw new EssReplaceException();
		}
		String sourceXpath = "/";
		for(int i=1;i<sourceArray.length;i++){
			if(i+1<sourceArray.length){
				sourceXpath = sourceXpath+sourceArray[i]+"/";
			}else{
				sourceXpath = sourceXpath+sourceArray[i];
			}
		}
		logger.debug("XML:"+sourceXpath);
		Node sourceNode = sourceDoc.selectSingleNode(sourceXpath);
		
		if(sourceNode != null){
			essNode.setText(sourceNode.getText());
			logger.info(sourceNode.getName()+"替换"+essNode.getText());
		}		
	}
	/*
	 * 删除xml
	 * */
	private void deleteXml(Element ruleEleDele){
		logger.info("DELETE替换："+ruleEleDele.getName());
		String essXpath = ruleEleDele.getPath();
		logger.info("DELETE:"+essXpath);
		Node delNode = essDoc.selectSingleNode(essXpath);
		essDoc.remove(delNode.detach());
		logger.info("删除"+delNode.getName());
	}
	/*
	 * 从规则文件取值
	 * */
	private void valueXml(Element ruleEleValue){
		logger.info("VALUE替换："+ruleEleValue.getName());
		String value = ruleEleValue.getText();
		String essXpath = ruleEleValue.getPath();
		logger.debug("VALUE:"+essXpath);
		Node valueNode = essDoc.selectSingleNode(essXpath);
		valueNode.setText(value);
		logger.info(valueNode.getName()+"赋值"+value);
	}
	/*
	 * array替换
	 * */
	@SuppressWarnings("unchecked")
	private void arrayXml(Element ruleEleArray) throws EssReplaceException{
		logger.info("ARRAY替换："+ruleEleArray.getName());
		String lyysrc = ruleEleArray.attributeValue("lyysrc");
		String[] lyysrcAraay = null;
		String essSourceMessageXml = null;
		Document sourceDoc = null;
		String sourceXpath = "/";
		if(lyysrc!=null&&!lyysrc.equals("")){
			logger.info("ARRAY.lyysrc:"+lyysrc);
			lyysrcAraay = lyysrc.split("\\.");
			String essRspReq = "_request_";
			if(lyysrcAraay[1].endsWith("Rsp")){
				essRspReq = "_response_";
			}
			essSourceMessageXml = (String)mapIn.get(lyysrcAraay[0]+essRspReq+"essMessageXml");
			if(essSourceMessageXml == null||essSourceMessageXml.trim().equals("")){
				return;
			}
		
			Document mainDoc = null;
			try {
				mainDoc = DocumentHelper.parseText(essSourceMessageXml);
			} catch (DocumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if(mainDoc == null){
				return;
			}
			Node servContNode = mainDoc.selectSingleNode("/UniBSS/SvcCont");
			essSourceMessageXml = servContNode.getText();
			if(essSourceMessageXml == null||essSourceMessageXml.trim().equals("")){
				return;
			}
			
			try {
				sourceDoc = DocumentHelper.parseText(essSourceMessageXml);
			} catch (DocumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw new EssReplaceException();
			}
			for(int i=1;i<lyysrcAraay.length;i++){
				sourceXpath = sourceXpath + lyysrcAraay[i] + "/";
			}
		}
		
		String lyymax = ruleEleArray.attributeValue("lyymax");
		int max = Integer.parseInt(lyymax);
		
		String essXpath1 = ruleEleArray.getPath();
		Element essElement = (Element)essDoc.selectSingleNode(essXpath1);
		Element essClone = (Element)essElement.clone();
		
		Element essParEle = essElement.getParent();
		essParEle.remove(essElement);
		for(int i=0;i<max;i++){
			essParEle.add((Element)essClone.clone());
		}
		
		Iterator<Element> arrIt = ruleEleArray.elementIterator();
		while(arrIt.hasNext()){
			Element subArrEle = arrIt.next();
			String essXpath = subArrEle.getPath();
			
			List<Node> essNodeList = essDoc.selectNodes(essXpath);			
			String subLyyType = subArrEle.attributeValue("lyytype");
			logger.info("节点类型："+subLyyType);
			if(subLyyType!=null&&!subLyyType.equals("")){
				if(subLyyType.equals("ARRAY")){
					arrayXml(subArrEle);
				}else if(subLyyType.equals("ARRAYVALUE")){
					logger.debug("ARRAYVALUE:"+subArrEle.getName());
					String text = subArrEle.getText();
					logger.debug("所有数据："+text);
					String[] textArr = text.split(",");
					logger.debug(textArr.length+":"+textArr[0]+":"+textArr[1]);
					String splitStr = textArr[0];
					if(splitStr.equals("|")){
						splitStr = "\\|";
					}
					String[] data = textArr[1].split(splitStr);
					logger.debug(data.length+":"+data[0]+":"+data[1]+":"+data[2]);
					if(data.length!=max){
						logger.error("规则文件配置有误！lyymax与数据条数不一致！");
						throw new EssReplaceException();
					}else if(essNodeList.size()!=max){
						logger.error("要替换的报文节点条数与lyymax数据条数不一致！");
						throw new EssReplaceException();
					}
					for(int i=0;i<max;i++){
						essNodeList.get(i).setText(data[i]);
						logger.info(essNodeList.get(i).getName()+"赋值"+data[i]);
					}
				}
			}else{
				logger.info("ARRAY:"+subArrEle.getName());
				String lyyname = subArrEle.attributeValue("lyyname");
				logger.debug("替换节点："+sourceXpath+lyyname);
				List<Node> sourceNodeList = sourceDoc.selectNodes(sourceXpath+lyyname);
				if(sourceNodeList.size()!=essNodeList.size()){
					logger.error("要替换的报文节点条数与源数据报文节点条数不一致！");
					throw new EssReplaceException();
				}else if(essNodeList.size()!=max){
					logger.error("规则文件配置有误！lyymax与数据条数不一致！");
					throw new EssReplaceException();
				}
				for(int i=0;i<max;i++){
					Node deNode = essNodeList.get(i);
					Node souNode = sourceNodeList.get(i);
					deNode.setText(souNode.getText());
					logger.info(deNode.getName()+"赋值"+souNode.getText());
				}
			}
		}
	}
}
